<template>
  <div class="flow_region">
    <div class="nodes-wrap">
      <div
        v-for="item in nodeTypeList"
        :key="item.type"
        class="node"
        draggable="true"
        @dragstart="drag($event, item)"
      >
        <div class="log">
          <img :src="item.logImg" alt="" />
        </div>
        <div class="name">{{ item.typeName }}</div>
      </div>
      <Button @click="saveData" style="margin-bottom: 10px">保存</Button>
      <br />
      <Button @click="toogleSelect">{{
        selectOpen ? "取消框选" : "框选"
      }}</Button>
    </div>
    <div
      id="flowWrap"
      ref="flowWrap"
      class="flow-wrap"
      @drop="drop($event)"
      @dragover="allowDrop($event)"
    >
      <div id="flow">
        <div
          v-show="auxiliaryLine.isShowXLine"
          class="auxiliary-line-x"
          :style="{
            width: auxiliaryLinePos.width,
            top: auxiliaryLinePos.y + 'px',
            left: auxiliaryLinePos.offsetX + 'px',
          }"
        ></div>
        <div
          v-show="auxiliaryLine.isShowYLine"
          class="auxiliary-line-y"
          :style="{
            height: auxiliaryLinePos.height,
            left: auxiliaryLinePos.x + 'px',
            top: auxiliaryLinePos.offsetY + 'px',
          }"
        ></div>

        <!-- vif切换 jsplumb初始化事件都没了 -->
        <drag-select
          attribute="attr"
          @change="selected = $event"
          style="width: 100%; height: 100%"
        >
          <flowNode
            v-for="item in data.nodeList"
            :id="item.id"
            :key="item.id"
            :attr="item.id"
            :dragSelected="selected.includes(String(item.id))"
            :node="item"
            @setNodeName="setNodeName"
            @deleteNode="deleteNode"
            @updateNodeStatus="updateNodeStatus"
            @changeLineState="changeLineState"
            @selectNode="selectNode"
            @removePosses="removePosses"
          ></flowNode>
        </drag-select>

        <!-- <flowNode
          v-else
          v-for="item in data.nodeList"
          :id="item.id"
          :key="item.id"
          :node="item"
          @setNodeName="setNodeName"
          @deleteNode="deleteNode"
          @updateNodeStatus="updateNodeStatus"
          @changeLineState="changeLineState"
          @selectNode="selectNode"
        ></flowNode> -->
      </div>
    </div>

    <!-- 选择区域示例 -->
    <!-- <drag-select
      attribute="attr"
      @change="selected = $event"
      style="width: 200px; padding: 50px"
    >
      <div
        v-for="item in [1, 2, 3]"
        :key="item"
        :attr="item"
        :class="{ 'item-selected-class': selected.includes(String(item)) }"
      >
        {{ item }}
      </div>
    </drag-select> -->

    <Drawer
      :mask="false"
      :closable="false"
      v-model="visibleDraw"
      width="200"
      :mask-closable="false"
      :transfer="false"
    >
      <span>节点名称</span>
      <Input
        v-model="currentNodeItem.nodeName"
        placeholder="please enter user name"
        style="margin: 10px"
      />
      <hr />
      {{ JSON.stringify(currentNodeItem) }}
    </Drawer>
  </div>
</template>

<script>
import { jsPlumb } from "jsplumb";
import { nodeTypeList } from "./config/init";
import {
  jsplumbSetting,
  jsplumbConnectOptions,
  jsplumbSourceOptions,
  jsplumbTargetOptions,
} from "./config/commonConfig";
import methods from "./config/methods";
// import data from "./config/data.json";
let data = JSON.parse(localStorage.getItem("data")) || {
  nodeList: [],
  lineList: [],
};
import flowNode from "./components/node-item";
import DragSelect from "drag-select-vue";
export default {
  name: "FlowEdit",
  components: {
    flowNode,
    DragSelect,
  },
  data() {
    return {
      visibleDraw: true,
      jsPlumb: null,
      currentItem: null,
      nodeTypeList: nodeTypeList,
      nodeTypeObj: {},
      data: {
        nodeList: [],
        lineList: [],
      },
      selectedList: [],
      jsplumbSetting: jsplumbSetting,
      jsplumbConnectOptions: jsplumbConnectOptions,
      jsplumbSourceOptions: jsplumbSourceOptions,
      jsplumbTargetOptions: jsplumbTargetOptions,
      auxiliaryLine: { isShowXLine: false, isShowYLine: false }, //对齐辅助线是否显示
      auxiliaryLinePos: {
        width: "100%",
        height: "100%",
        offsetX: 0,
        offsetY: 0,
        x: 20,
        y: 20,
      },
      commonGrid: [5, 5], //节点移动最小距离
      selectModuleFlag: false, //多选标识
      rectAngle: {
        px: "", //多选框绘制时的起始点横坐标
        py: "", //多选框绘制时的起始点纵坐标
        left: 0,
        top: 0,
        height: 0,
        width: 0,
      },
      currentNodeId: "",
      selected: [], //选中框选元素
      selectOpen: false, //开启框选
    };
  },
  computed: {
    currentNodeItem: function () {
      return (
        this.data.nodeList.find((node) => node.id == this.currentNodeId) || {}
      );
    },
  },
  mounted() {
    this.jsPlumb = jsPlumb.getInstance();
    this.initNodeTypeObj();
    this.initNode();
    // this.fixNodesPosition(); //初始化节点居中
    this.$nextTick(() => {
      this.init();
    });
  },
  methods: {
    ...methods,
    initNodeTypeObj() {
      nodeTypeList.map((v) => {
        this.nodeTypeObj[v.type] = v;
      });
    },
    initNode() {
      // json 无法直接存放图片资源，通过nodeTypeObj映射
      this.data.lineList = data.lineList;
      data.nodeList.map((v) => {
        v.logImg = this.nodeTypeObj[v.type].logImg;
        v.log_bg_color = this.nodeTypeObj[v.type].log_bg_color;
        this.data.nodeList.push(v);
      });
    },
    // 保存节点、连线数据
    saveData() {
      console.log(this.data);
      localStorage.setItem("data", JSON.stringify(this.data));
    },
    // 切换框选状态
    toogleSelect() {
      this.selectOpen = !this.selectOpen;
    },
  },
  watch: {
    selected(newval, oldval) {
      if (oldval.length) {
        // 移除全部分组
        this.jsPlumb.removeFromAllPosses(oldval);
      }
      if (newval.length) {
        // 添加至分组
        this.jsPlumb.addToPosse(newval, "posse");
      }
    },
  },
};
</script>

<style lang="less" scoped>
.flow_region {
  display: flex;
  width: 90%;
  height: 90%;
  margin: 20px auto;
  border: 1px solid #ccc;
  .nodes-wrap {
    width: 150px;
    height: 100%;
    border-right: 1px solid #ccc;
    .node {
      display: flex;
      height: 40px;
      width: 80%;
      margin: 5px auto;
      border: 1px solid #ccc;
      line-height: 40px;
      &:hover {
        cursor: grab;
      }
      &:active {
        cursor: grabbing;
      }
      .log {
        width: 40px;
        height: 40px;
      }
      .name {
        width: 0;
        flex-grow: 1;
      }
    }
  }
  .flow-wrap {
    height: 100%;
    position: relative;
    overflow: hidden;
    outline: none !important;
    flex-grow: 1;
    background-image: url("../assets/point.png");
    overflow: auto;
    #flow {
      position: relative;
      width: 120%;
      height: 120%;
      .auxiliary-line-x {
        position: absolute;
        border: 0.5px dashed #2ab1e8;
        z-index: 9999;
      }
      .auxiliary-line-y {
        position: absolute;
        border: 0.5px dashed #2ab1e8;
        z-index: 9999;
      }
    }
  }
}
</style>

<style lang="less">
// 连线动画样式
.jtk-connector.active {
  z-index: 9999;
  path {
    stroke: #3ec791;
    stroke-width: 1.5;
    animation: ring;
    animation-duration: 3s;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    stroke-dasharray: 5;
  }
}
@keyframes ring {
  from {
    stroke-dashoffset: 50;
  }
  to {
    stroke-dashoffset: 0;
  }
}
.item-selected-class {
  border: 1px solid red;
}
</style>